package com.siyoumi.component;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.siyoumi.config.SysConfig;
import com.siyoumi.exception.EnumSys;
import com.siyoumi.util.*;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.time.LocalDateTime;
import java.util.Map;

@Service
public class XJwt {
    static public XJwt getBean() {
        return XSpringContext.getBean(XJwt.class);
    }

    private String getPrivateKey() {
        String privateKey = SysConfig.getIns().getJwtPk();
        if (XStr.isNullOrEmpty(privateKey)) {
            privateKey = "abc123QWER###!";
        }
        return privateKey;
    }


    public String getToken(Map<String, Object> arr) {
        return getToken(arr, 3600);
    }

    /**
     * 获取token
     *
     * @return String
     */
    public String getToken(Map<String, Object> arr, Integer expireSecond) {
        return getToken(arr, getPrivateKey(), expireSecond);

    }

    public String getToken(Map<String, Object> arr, String privateKey, Integer expireSecond) {
        return JWT.create()
                .withClaim("map", arr)
                .withExpiresAt(Instant.now().plusSeconds(expireSecond))
                .sign(Algorithm.HMAC256(privateKey));
    }


    /**
     * 检查token
     *
     * @return Boolean
     */
    public boolean checkToken(String token) {
        XReturn r = parseToken(token);
        return r.ok();
    }


    /**
     * 解析token
     *
     * @return XReturn
     */
    public XReturn parseToken(String token) {
        XReturn r;
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(getPrivateKey())).build();
            DecodedJWT decodedJWT = verifier.verify(token);//解析失败，会报错
            //
            String payload = decodedJWT.getPayload();
            XLog.debug(this.getClass(), "payload:", payload);
            String payload_dec = XStr.base64Dec(payload);
            XLog.debug(this.getClass(), "payload_dec:", payload_dec);
            //内容
            Map<String, Object> json = XStr.toJson(payload_dec);
            r = XReturn.parse((Map<String, Object>) json.get("map"));
            //过期时间
            LocalDateTime expires_at = XDate.parseTimestamp(decodedJWT.getExpiresAtAsInstant().getEpochSecond());
            r.put("expire_at", XDate.toDateTimeString(expires_at));
        } catch (TokenExpiredException e) {
            //token过期
            r = EnumSys.TOKEN_EXPIRED.getR();
        } catch (Exception e) {
            r = EnumSys.TOKEN_ERR.getR();
        }

        return r;
    }
}
